home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / lisp / resume.el < prev    next >
Lisp/Scheme  |  1993-05-02  |  6KB  |  165 lines

  1. ;;; resume.el --- process command line args from within a suspended Emacs job
  2.  
  3. ;; Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Joe Wells <jbw@bucsf.bu.edu>
  6. ;; Adapted-By: ESR
  7. ;; Keywords: processes
  8.  
  9. ;; This file is part of GNU Emacs.
  10.  
  11. ;; GNU Emacs is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 1, or (at your option)
  14. ;; any later version.
  15.  
  16. ;; GNU Emacs is distributed in the hope that it will be useful,
  17. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;; GNU General Public License for more details.
  20.  
  21. ;; You should have received a copy of the GNU General Public License
  22. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  23. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  
  25. ;;; Commentary:
  26.  
  27. ;; Theory: the first time you start Emacs, command line arguments are
  28. ;; handled normally.  Then, you suspend your emacs job.  When you want to edit
  29. ;; something else, you type "emacs filename" as usual, but instead of
  30. ;; starting a new emacs job, the old job is resumed instead, and the command
  31. ;; line arguments are placed in a file where the old emacs job looks for
  32. ;; them.
  33.  
  34. ;; Stephan Gildea suggested bug fix (gildea@bbn.com).
  35. ;; Ideas from Michael DeCorte and other people.
  36.  
  37. ;; For csh users, insert the following alias in your .cshrc file
  38. ;; (after removing the leading double semicolons, of course):
  39. ;;
  40. ;;# The following line could be just EMACS_CMD=emacs, but this depends on
  41. ;;# your site.
  42. ;;if (! $?EMACS_CMD) set EMACS_CMD=emacs
  43. ;;set JOBS_FILE=/tmp/jobs.$USER.$$
  44. ;;set ARGS_FILE=~/.emacs_args
  45. ;;set STOP_PATT='^\[[0-9]*\] *[ +-] Stopped ............ '
  46. ;;set SUNVIEW_CMD='emacstool -nw -f emacstool-init -f server-start'
  47. ;;set X_CMD=\'\''$EMACS_CMD -i -f server-start'
  48. ;;alias emacs \
  49. ;;' \\
  50. ;;   jobs >! "$JOBS_FILE" \\
  51. ;;   && grep "$STOP_PATT$EMACS_CMD" "$JOBS_FILE" >& /dev/null \\
  52. ;;   && echo `pwd` \!* >! "$ARGS_FILE" && ""fg %$EMACS_CMD \\
  53. ;;|| if (! -e ~/.emacs_server || -f ~/.emacs_server) set status=1 \\
  54. ;;   && emacsclient \!* \\
  55. ;;|| @ status=1 - $?DISPLAY && eval "$X_CMD -i \!* &" \\
  56. ;;|| @ status=1 - $?WINDOW_PARENT && eval "$SUNVIEW_CMD \!* &" \\
  57. ;;|| ""$EMACS_CMD -nw \!* \\
  58. ;;'
  59. ;;
  60. ;; The alias works as follows:
  61. ;; 1. If there is a suspended Emacs job that is a child of the
  62. ;; current shell, place its arguments in the ~/.emacs_args file and
  63. ;; resume it.
  64. ;; 2. Else if the ~/.emacs_server socket has been created, presume an
  65. ;; Emacs server is running and attempt to connect to it.  If no Emacs
  66. ;; server is listening on the socket, this will fail.
  67. ;; 3. Else if the DISPLAY environment variable is set, presume we are
  68. ;; running under X Windows and start a new GNU Emacs process in the
  69. ;; background as an X client.
  70. ;; 4. Else if the WINDOW_PARENT environment variable is set, presume we
  71. ;; are running under SunView and start an emacstool process in the
  72. ;; background.
  73. ;; 5. Else start a regular Emacs process.
  74. ;;
  75. ;; Notes:
  76. ;; The output of the "jobs" command is not piped directly into "grep"
  77. ;; because that would run the "jobs" command in a subshell.
  78. ;; Before resuming a suspended emacs, the current directory and all
  79. ;; command line arguments are placed in a file name ~/.emacs_args.
  80. ;; The "-nw" switch to Emacs means no windowing system.
  81.  
  82. ;; Insert this in your .emacs file:
  83. ;;(add-hook 'suspend-hook 'resume-suspend-hook)
  84.  
  85. ;; Finally, put the rest in a file named "resume.el" in a lisp library
  86. ;; directory.
  87.  
  88. ;;; Code:
  89.  
  90. (defvar resume-emacs-args-file (expand-file-name "~/.emacs_args")
  91.   "*This file is where arguments are placed for a suspended emacs job.")
  92.  
  93. (defvar resume-emacs-args-buffer " *Command Line Args*"
  94.   "Buffer that is used by resume-process-args.")
  95.  
  96. (defun resume-process-args ()
  97.   "Handler for command line args given when Emacs is resumed."
  98.   (let ((start-buffer (current-buffer))
  99.     (args-buffer (get-buffer-create resume-emacs-args-buffer))
  100.     length args)
  101.     (unwind-protect
  102.     (progn
  103.       (set-buffer args-buffer)
  104.       (erase-buffer)
  105.       ;; get the contents of resume-emacs-args-file
  106.       (condition-case ()
  107.           (let ((result (insert-file-contents resume-emacs-args-file)))
  108.         (setq length (car (cdr result))))
  109.         ;; the file doesn't exist, ergo no arguments
  110.         (file-error
  111.           (erase-buffer)
  112.           (setq length 0)))
  113.       (if (<= length 0)
  114.           (setq args nil)
  115.         ;; get the arguments from the buffer
  116.         (goto-char (point-min))
  117.         (while (not (eobp))
  118.           (skip-chars-forward " \t\n")
  119.           (let ((begin (point)))
  120.         (skip-chars-forward "^ \t\n")
  121.         (setq args (cons (buffer-substring begin (point)) args)))
  122.           (skip-chars-forward " \t\n"))
  123.         ;; arguments are now in reverse order
  124.         (setq args (nreverse args))
  125.         ;; make sure they're not read again
  126.         (erase-buffer))        
  127.       (resume-write-buffer-to-file (current-buffer) resume-emacs-args-file)
  128.       ;; if nothing was in buffer, args will be null
  129.       (or (null args)
  130.           (setq default-directory (file-name-as-directory (car args))
  131.             args (cdr args)))
  132.       ;; actually process the arguments
  133.       (command-line-1 args))
  134.       ;; If the command line args don't result in a find-file, the
  135.       ;; buffer will be left in args-buffer.  So we change back to the
  136.       ;; original buffer.  The reason I don't just use
  137.       ;; (let ((default-directory foo))
  138.       ;;    (command-line-1 args))
  139.       ;; in the context of the original buffer is because let does not
  140.       ;; work properly with buffer-local variables.
  141.       (if (eq (current-buffer) args-buffer)
  142.       (set-buffer start-buffer)))))
  143.  
  144. ;;;###autoload
  145. (defun resume-suspend-hook ()
  146.   "Clear out the file used for transmitting args when Emacs resumes."
  147.   (save-excursion
  148.     (set-buffer (get-buffer-create resume-emacs-args-buffer))
  149.     (erase-buffer)
  150.     (resume-write-buffer-to-file (current-buffer) resume-emacs-args-file)))
  151.  
  152. (defun resume-write-buffer-to-file (buffer file)
  153.   "Writes the contents of BUFFER into FILE, if permissions allow."
  154.   (if (not (file-writable-p file))
  155.       (error "No permission to write file %s" file))
  156.   (save-excursion
  157.     (set-buffer buffer)
  158.     (clear-visited-file-modtime)
  159.     (save-restriction
  160.       (widen)
  161.       (write-region (point-min) (point-max) file nil 'quiet))
  162.     (set-buffer-modified-p nil)))
  163.  
  164. ;;; resume.el ends here
  165.